package com.yr.feiyu.common.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSONObject;

/**
 * 
 * <p class="detail">
 * 功能：封装kindEditor保存文件, 读取文件空间
 * </p>
 * @ClassName: KindEditorUtil 
 * @version V1.0  
 * @date 2015年8月15日 
 * @author <a href="mailto:1435290472@qq.com">zq</a>
 */
public class KindEditorUtil {
	public static final String ERROR_CODE = "1";
	public static final String SUCCESS_CODE = "0";
	
	/**
	 * 
	 * <p class="detail">
	 * 功能：保存上传的文件
	 * </p>
	 * @date 2015年8月15日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param request
	 * @param savePath
	 * @param saveUrl
	 * @return
	 */
	public static String fileUpload(HttpServletRequest request,String savePath,String saveUrl){
			if(!ServletFileUpload.isMultipartContent(request)){  
	           return getResult(ERROR_CODE,"请选择文件。");  
			}  
			//检查目录  
			/*File uploadDir = new File(savePath); 
	       	if(!uploadDir.isDirectory()){ 
	           	return getError("上传目录不存在。"); 
	       	} 
	       	//检查目录写权限 
	       	if(!uploadDir.canWrite()){ 
	           	return getError("上传目录没有写权限。"); 
	       	}*/  
	 
			String dirName = request.getParameter("dir");  
			if (dirName == null) {  
				dirName = "image";  
			}  
	         
			//定义允许上传的文件扩展名  
			Map<String, String> extMap = new HashMap<String, String>();  
			extMap.put("image", "gif,jpg,jpeg,png,bmp");  
			extMap.put("flash", "swf,flv");  
			extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");  
			extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,xml,txt,zip,rar,gz,bz2");  
	         
			if(!extMap.containsKey(dirName)){  
				return getResult(ERROR_CODE,"目录名不正确。");  
			}
			
			//创建文件夹  
			savePath += dirName + "/";  
			saveUrl += dirName + "/";  
			File saveDirFile = new File(savePath);  
			if (!saveDirFile.exists()) {  
				saveDirFile.mkdirs();  
			}
			
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");  
			String ymd = sdf.format(new Date());  
			savePath += ymd + "/";  
			saveUrl += ymd + "/";  
			File dirFile = new File(savePath);  
			if (!dirFile.exists()) {  
				dirFile.mkdirs();  
			}  

			//最大文件大小 10M
			long maxSize = 1024000;
			
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			Iterator<?> item = multipartRequest.getFileNames();
			
			//保存文件名
			String newFileName = "";
			
			while (item.hasNext()) {  
				String fileName = (String) item.next();
				MultipartFile file = multipartRequest.getFile(fileName);
				
				//检查文件大小  
				if(file.getSize() > maxSize){  
					return getResult(ERROR_CODE,"上传文件大小超过限制10M。"); 
				}  
				//检查扩展名  
				String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
				//fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();  
				if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){  
					return getResult(ERROR_CODE,"上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。");  
				}  
	 
				SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");  
				newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;  
				try{  
					File uploadedFile = new File(savePath, newFileName);  
					byte[] data = new byte[(int) file.getSize()];
					InputStream in = file.getInputStream();
					OutputStream out = new FileOutputStream(uploadedFile);
					in.read(data);
					out.write(data);
					in.close();
					out.close();
				}catch(Exception e){  
					return getResult(ERROR_CODE,"上传文件失败。");  
				}
			}
			
			return getResult(SUCCESS_CODE, saveUrl + newFileName);
	}
	
	/**
	 * 
	 * <p class="detail">
	 * 功能：返回结果封装  
	 * 失败的时候  message
	 * 成功返回 文件目录的url，供前端读取显示
	 * </p>
	 * @date 2015年8月15日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param code
	 * @param errorMsg
	 * @return
	 */
	private static String getResult(String code,String msg) {  
		Map<String, Object> errorMap = new HashMap<String, Object>();  
		errorMap.put("error", code);
		if(code.equals(ERROR_CODE)){
			errorMap.put("message", msg);
		}else{
			errorMap.put("url", msg);
		}
		String json = JSONObject.toJSONString(errorMap);
				//JsonUtil.fromObject(errorMap);
		return json;  
	}
	
	
	/**
	 * 
	 * <p class="detail">
	 * 功能：文件空间
	 * </p>
	 * @date 2015年8月16日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param request
	 * @param rootPath
	 * @param rootUrl
	 * @return
	 */
	public static String fileManager(HttpServletRequest request,String rootPath,String rootUrl){
		//图片扩展名  
		String[] fileTypes = new String[]{"gif", "jpg", "jpeg", "png", "bmp"};  

		String dirName = request.getParameter("dir");  
			if (dirName != null) {  
				if(!Arrays.<String>asList(new String[]{"image", "flash", "media", "file"}).contains(dirName)){  
					return "Invalid Directory name.";  
				}  
				rootPath += dirName + "/";  
				rootUrl += dirName + "/";  
				File saveDirFile = new File(rootPath);  
				if (!saveDirFile.exists()) {  
					saveDirFile.mkdirs();  
				}  
			}  
			//根据path参数，设置各路径和URL  
			String path = request.getParameter("path") != null ? request.getParameter("path") : "";  
			String currentPath = rootPath + path;  
			String currentUrl = rootUrl + path;  
			String currentDirPath = path;  
			String moveupDirPath = "";  
			if (!"".equals(path)) {  
				String str = currentDirPath.substring(0, currentDirPath.length() - 1);  
				moveupDirPath = str.lastIndexOf("/") >= 0 ? str.substring(0, str.lastIndexOf("/") + 1) : "";  
			}  

			//排序形式，name or size or type  
			String order = request.getParameter("order") != null ? request.getParameter("order").toLowerCase() : "name";  

			//不允许使用..移动到上一级目录  
			if (path.indexOf("..") >= 0) {  
				return "Access is not allowed.";  
			}  
			//最后一个字符不是/  
			if (!"".equals(path) && !path.endsWith("/")) {  
				return "Parameter is not valid.";  
			}  
			//目录不存在或不是目录  
			File currentPathFile = new File(currentPath);  
			if(!currentPathFile.isDirectory()){  
				return "Directory does not exist.";  
			}  

			//遍历目录取的文件信息  
			List<Map<String, Object>> fileList = new ArrayList<Map<String, Object>>();  
			if(currentPathFile.listFiles() != null) {  
				for (File file : currentPathFile.listFiles()) {  
					Hashtable<String, Object> hash = new Hashtable<String, Object>();  
					String fileName = file.getName();  
					if(file.isDirectory()) {  
						hash.put("is_dir", true);  
						hash.put("has_file", (file.listFiles() != null));  
						hash.put("filesize", 0L);  
						hash.put("is_photo", false);  
						hash.put("filetype", "");  
					} else if(file.isFile()){  
						String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();  
						hash.put("is_dir", false);  
						hash.put("has_file", false);  
						hash.put("filesize", file.length());  
						hash.put("is_photo", Arrays.<String>asList(fileTypes).contains(fileExt));  
						hash.put("filetype", fileExt);  
					}  
					hash.put("filename", fileName);  
					hash.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified()));  
					fileList.add(hash);  
				}  
			}  

			if ("size".equals(order)) {  
				Collections.sort(fileList, new Comparator<Map<String, Object>>() {
					public int compare(Map<String, Object> hashA, Map<String, Object> hashB) {  
						if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {  
							return -1;  
						} else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {  
							return 1;  
						} else {  
							if (((Long)hashA.get("filesize")) > ((Long)hashB.get("filesize"))) {  
								return 1;  
							} else if (((Long)hashA.get("filesize")) < ((Long)hashB.get("filesize"))) {  
								return -1;  
							} else {  
								return 0;  
							}  
						}  
					}  
				});  
			} else if ("type".equals(order)) {  
				Collections.sort(fileList, new Comparator<Map<String, Object>>() {
					public int compare(Map<String, Object> hashA, Map<String, Object> hashB) {  
						if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {  
							return -1;  
						} else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {  
							return 1;  
						} else {  
							return ((String)hashA.get("filetype")).compareTo((String)hashB.get("filetype"));  
						}  
					} 
				});  
			} else {  
				Collections.sort(fileList, new Comparator<Map<String, Object>>() {
					public int compare(Map<String, Object> hashA, Map<String, Object> hashB) {  
						if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) {  
							return -1;  
						} else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) {  
							return 1;  
						} else {  
							return ((String)hashA.get("filename")).compareTo((String)hashB.get("filename"));  
						}  
					} 
				}); 
			}  
			Map<String, Object> result = new HashMap<String, Object>();  
			result.put("moveup_dir_path", moveupDirPath);  
			result.put("current_dir_path", currentDirPath);  
			result.put("current_url", currentUrl);  
			result.put("total_count", fileList.size());  
			result.put("file_list", fileList);  
				
			String json = JSONObject.toJSONString(result);

		return json;  
	}
}
